package com.android.msntop.services;

import java.net.URL;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;

import com.android.msntop.Msntop;

public class PingService extends Service {
	
	private static String PINGCMD = "ping -q -c ";
	public static int PING_ERROR = 2;
	public static int PING_OK = 0;
	public static int PING_DOWN = 1;
	// Message actions
	public static final int PING_REQUEST = 1;
	protected static final int PING_RESPONSE = 2;
	public static final int PING_REQUEST_WPACKETS = 3;
	public static final int PING_REQUEST_WURL = 4;
	
	public static final int DEFAULT_PACKETS = 2;
	

	/* Do we need callbacks here ? */
	final RemoteCallbackList<IPingServiceCallBack> callBacks
	= new RemoteCallbackList<IPingServiceCallBack>();

	@Override
	public void onCreate() {

		//Log.i("PINGSERVICE", "in OnCreate");
		super.onCreate();
		// and wait patiently for someone to send a request
	}

	public void onStart(Intent intent, int startId)
	{
		//Log.i("PINGSERVICE", "in Start");
		super.onStart(intent, startId);
	}

	public void onDestroy() {
		
		//Log.i("PINGSERVICE", "in Destroy");
		callBacks.kill();
		mHandler.removeMessages(PING_REQUEST);
		super.onDestroy();
	}


	public IBinder onBind(Intent intent) {
		return mBinder;
	}
	
	public void isHostUrlUp(final URL url)
	{
		Thread t = new Thread() {
			public void run() {
				int status = Msntop.PING_DOWN;

				try {
					int iStatusCode  = WebUtils.doHeadUrl( url.toString() );
					if( iStatusCode == 200 )
					{
						status = Msntop.PING_OK;
					}
				} catch (Exception e) {
					e.printStackTrace();
					status = Msntop.PING_ERROR;
				}

				Message m = mHandler.obtainMessage(PING_RESPONSE, status, 0, url.getHost());
				mHandler.handleMessage(m);
				//Log.i("Ping service", "returning status " + status);
				return;
			}
		};

		t.start();
	}
           
	public void isHostUp(final String host)
	{
		isHostUp(host, DEFAULT_PACKETS);
	}
	
	public void isHostUp(final String host, final int numPackets){


		Thread t = new Thread() {
			public void run() {

				int status = -2;
				Runtime r = Runtime.getRuntime();
				Process p;
				//Log.i("Ping service", "Processing ping request for " + host); 
				try {
					p = r.exec(PINGCMD + numPackets + " " + host);
					//Log.i("Ping service", "Exec " + PINGCMD + host);
					status = p.waitFor();

				} catch (Exception e) {

					e.printStackTrace();
					status = -2;
				}
				Message m = mHandler.obtainMessage(PING_RESPONSE, status, 0, host);
				mHandler.handleMessage(m);
				//Log.i("Ping service", "returning status " + status);
				return;
			}
		};
		
		t.start();
	}
	/* PingInterface defined through AIDL */
	private final IPingService.Stub mBinder = new IPingService.Stub() {

		public void isHostUp(String host) throws RemoteException 
		{
			//Log.i("PingServiceBinder", "Got from app:" + host + " dispatching local request");
			mHandler.handleMessage(mHandler.obtainMessage(PING_REQUEST, host));
		}
		public void isHostUrlUp(String host, String optPath) throws RemoteException 
		{
			try
			{
				URL url = new URL( "http", host, optPath );
				mHandler.handleMessage(mHandler.obtainMessage(PING_REQUEST_WURL, url));
			}
			catch( Exception e )
			{
				throw new RemoteException();
			}
		}
		public void registerCallback(IPingServiceCallBack callback)
		throws RemoteException {
			if (callBacks != null) callBacks.register(callback);

		}
		public void unregisterCallback(IPingServiceCallBack callback)
		throws RemoteException {
			if (callBacks != null) callBacks.register(callback);

		}
		public void isHostUpP(String host, int nump) throws RemoteException {
			mHandler.handleMessage(mHandler.obtainMessage(PING_REQUEST_WPACKETS, nump, 0,host));
		}
	};
	
	private final Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			
			case PING_REQUEST_WURL: 
			{
				URL url = (URL)msg.obj;
				isHostUrlUp(url); 
				break;
			}
			case PING_REQUEST: 
			{
				String host = (String)msg.obj;
				if(host == null)
				{
					
					//Do something - should return back a message 
				}
				isHostUp(host); 
				break;
			}
			case PING_REQUEST_WPACKETS: 
			{
				String host = (String)msg.obj;
				if(host == null)
				{
					
					//Do something - should return back a message 
				}
				isHostUp(host,msg.arg1); 
				break;
			}
			case PING_RESPONSE:
				
				int n = callBacks.beginBroadcast();
				for (int i=0; i<n; i++) 
				{
					try {
						callBacks.getBroadcastItem(i).hostStatus((String)msg.obj, msg.arg1);
					} catch (RemoteException e) {

					}
					callBacks.finishBroadcast();

				} 
				break;
				
			default:
				super.handleMessage(msg);
			}
		}
	};


}
